<template>
    <el-form :inline="inline" class="form-detail" :label-width="labelWidth" v-loading="formLoading" :label-position="labelPosition">
        <el-row type="flex" v-for="(rowItem,rowIndex) in computedLayout" :key="rowIndex">
            <el-col :span="24/rowItem > layoutColMax ? (inline?layoutColMax:24/rowItem): 24/rowItem" v-for="(colItem,colIndex) in rowItem" :key="colIndex">
        <el-form-item :label="item.element.label" v-for="(item,index) in [formItems[arrayBeforeIndexSum(rowIndex,computedLayout) + colItem-1]]"  :key="index">
            <template v-if="item.element.type == 'image'">
                <template v-if="defaultValue == getItemvalue(item)">{{defaultValue}}</template>
                <el-image v-else class="image-thumbnail" :src="getItemvalue(item)"
                          :preview-src-list="[getItemvalue(item)]"
                          style="width: 25px;height:25px;cursor: pointer;border: none;">
                    <i slot="error" class="el-icon-picture-outline"></i>
                </el-image>
            </template>
            <div v-else-if="item.element.type == 'html'" v-html="getItemvalue(item)"></div>
            <Table v-else-if="item.element.type == 'table'" :columns="item.element.table.columns" :data="getItemvalue(item)" :show-toolbar="false"></Table>
            <el-button v-else-if="item.element.type == 'button'" :type="item.element.button.type" @click="buttonClick(item.element.button)">{{getItemvalue(item)}}</el-button>
            <div v-else>{{  getItemvalue(item)}}</div>
        </el-form-item>
            </el-col>
        </el-row>
    </el-form>
</template>

<script>
    import objectMixin from "../../mixin/ObjectMixin"
    import Table from './Table.vue'
    let defaultItemValue = '-'
    export default {
        name: "FormDetail",
        mixins:[objectMixin],
        components:{
            Table
        },
        props:{
            // left right top
            labelPosition: {
                type: String,
                default: 'left'
            },
            // 表单加载状态
            loading:{
                type: Boolean,
                default:false
            },
            labelWidth:{
                type: String,
                default: '100px'
            },
            inline:{
                type: Boolean,
                default: false
            },
            // 布局一个数据[1,2,2],表示第一行1个第二行2个第三行2个
            layout: {
                type: Array,
                default: function () {
                    return []
                }
            },
            // 布局一个数字，指定几列，layout属性和该属性只能指定一个
            layoutColumnNum: {
                type: Number,
                default: null
            },
            // 布局的列最大值
            layoutColMax:{
                type: Number,
                default: 5
            },
            // 表单项定义信息,参考form.vue的格式，默认文本展示
            formItems:{
                type: Array,
                default: function () {
                    return []
                }
            },
            // 表单项的值
            formData:{
                type: Object,
                default: null
            },
            // 数据初始化的url，
            initDataUrl:String,
            // 数据初始化的url请求完数据后，预处理回调,参数为数据实体对象而非响应对象，请依然返回实体
            handleInitData:Function
        },
        computed:{
            // 合理化layout
            computedLayout (){
                let tempLayout = []
                let shouldTotal = this.formItems.length

                if (this.layout.length == 0) {
                    if(this.layoutColumnNum > 0){
                        if(this.layoutColumnNum > shouldTotal){
                            for (let i = 0; i < shouldTotal; i++) {
                                tempLayout.push(1)
                            }
                        }else{
                            let col = Math.floor(shouldTotal/this.layoutColumnNum)
                            for (let i = 0; i < col; i++) {
                                tempLayout.push(this.layoutColumnNum)
                            }
                            this.arrayAppendOneIfNeccesary(tempLayout,shouldTotal)
                        }
                    }else{
                        if(this.inline){
                            tempLayout.push(shouldTotal)
                        }else{
                            for (let i = 0; i < shouldTotal; i++) {
                                tempLayout.push(1)
                            }
                        }

                    }

                }else {
                    tempLayout.concat(this.layout)
                    this.arrayAppendOneIfNeccesary(tempLayout,shouldTotal)
                }
                return tempLayout
            },
        },
        data () {
            return {
                formLoading: false,
                localFormData: this.formData,
                defaultValue: defaultItemValue
            }
        },
        mounted(){
          this.initDataByUrl()
        },
        methods:{
            arrayAppendOneIfNeccesary(array, shouldTotal) {
                let  realTotal = 0
                array.forEach(item => {
                    realTotal += item
                })
                if(realTotal < shouldTotal){
                    for (let i = 0; i < shouldTotal - realTotal; i++) {
                        array.push(1)
                    }
                }
                else if(realTotal > shouldTotal){
                    throw new Error('layout总数多于元素总数');
                }
            },
            arrayBeforeIndexSum(index,array){
                let r = 0;
                for(let i = 0;i < index; i++){
                    r += array[i]
                }
                return r
            },
            getItemvalue(item){
                if(typeof item.field.value == 'function'){
                    return item.field.value(this.localFormData)
                }else{
                    let value = this.$_object_getValue(this.localFormData,item.field.name,this.localFormData)
                    if(typeof value == 'boolean'){
                        return value ? '是' : '否'
                    }else if(value == null){
                        // 取默认值
                        value = item.field.value
                        if(value == null || value == undefined){
                            return defaultItemValue
                        }else {
                            return value
                        }
                    }
                    return value
                }
            },
            initDataByUrl(){
                if(this.initDataUrl){
                    this.formLoading = true
                    this.axios.get(this.initDataUrl).then(res => {
                        let data = res.data
                        if(this.handleInitData){
                            data = this.handleInitData(data)
                        }
                        this.localFormData = data
                    }).catch(error => {
                        if(error.response){
                            if(error.response.status == 404){
                                this.$message.error('数据不存在，请刷新数据再试')
                            }else {
                                this.$message.error(error.response.data.msg)
                            }
                        }else {
                            this.$message.error('网络错误或服务不可用')
                        }
                    }).finally(()=>{
                        this.formLoading = false
                    })
                }
            },
            buttonClick(button){
                if(typeof button.action == 'function'){
                    button.action(this.localFormData,button.params)
                    return
                }
                switch (button.action) {
                    case 'nav':{
                        let url = button.url
                        if(typeof url == 'function'){
                            url = button.url(this.localFormData)
                        }
                        this.$router.push(url)
                        break;
                    }

                }
            },
        },
        watch:{
            formData (val){
                this.localFormData = val
            },
            loading(val){
                this.formLoading = val
            }
        }
    }
</script>

<style scoped>
    .form-detail .image-thumbnail{
        border: 1px solid #d7dae2;
        width: 25px;
        height:25px;
        cursor: pointer;
    }
</style>
<style>
    .form-detail label {
        width: 150px;
        color: #99a9bf !important;
    }
</style>